package com.wstuo.common.config.dictionary.service;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.wstuo.common.config.category.dao.IEventCategoryDAO;
import com.wstuo.common.config.category.entity.EventCategory;
import com.wstuo.common.config.dictionary.dao.IDataDictionaryGroupDAO;
import com.wstuo.common.config.dictionary.dto.DataDictionaryGroupDTO;
import com.wstuo.common.config.dictionary.dto.DataDictionaryGroupQueryDTO;
import com.wstuo.common.config.dictionary.entity.DataDictionaryGroup;
import com.wstuo.common.dto.PageDTO;
import com.wstuo.common.exception.ApplicationException;
import com.wstuo.common.file.csv.CSVReader;
import com.wstuo.common.file.csv.CSVWriter;
import com.wstuo.common.security.utils.FileEncodeUtils;
import com.wstuo.common.security.utils.LanguageContent;
import com.wstuo.common.util.StringUtils;

/**
 * 数据字典分组业务类
 * 
 * @author QXY
 */
public class DataDictionaryGroupService implements IDataDictionaryGroupService {
	private static final Logger LOGGER = Logger.getLogger(DataDictionaryGroupService.class );
	@Autowired
	private IDataDictionaryGroupDAO dataDictionaryGroupDAO;
	@Autowired
	private IEventCategoryDAO eventCategoryDAO;
	/**
	 * 分页查询字典分组.
	 * 
	 * @param redto 查询DTO
	 * @return PageDTO 分页数据
	 */
	@SuppressWarnings("unchecked")
	@Transactional
	public PageDTO findDictionaryGroupByPage(DataDictionaryGroupQueryDTO redto) {

		PageDTO pageDTO = dataDictionaryGroupDAO.findpager(redto);
		List<DataDictionaryGroup> lists = pageDTO.getData();
		List<DataDictionaryGroupDTO> ddGroupDTOs = new ArrayList<DataDictionaryGroupDTO>(
				lists.size());
		for (DataDictionaryGroup ddGroup : lists) {
			DataDictionaryGroupDTO ddGroupDTO = new DataDictionaryGroupDTO();
			ddGroupDTO.setGroupName(ddGroup.getGroupName());
			ddGroupDTO.setGroupNo(ddGroup.getGroupNo());
			ddGroupDTO.setGroupCode(ddGroup.getGroupCode());
			ddGroupDTO.setDataFlag(ddGroup.getDataFlag());
			ddGroupDTO.setGroupType(ddGroup.getGroupType());
			ddGroupDTOs.add(ddGroupDTO);
		}
		pageDTO.setData(ddGroupDTOs);
		return pageDTO;
	}

	/**
	 * 保存字典分组.
	 * 
	 * @param dto  DTO
	 */
	@Transactional
	public void saveDataDictionaryGroup(DataDictionaryGroupDTO dto) {
		Long categoryId=0l;
		if("tree".equals(dto.getGroupType())){//添加树节构
			EventCategory eventCategory = new EventCategory();
			//分类名称
			eventCategory.setEventName(dto.getGroupName());
			eventCategory.setScores(0);
			eventCategory.setCategoryRoot(dto.getGroupCode());
			eventCategoryDAO.save(eventCategory);
			eventCategory.setPath(eventCategory.getEventId()+"/");
			categoryId=eventCategory.getEventId();
		}
		DataDictionaryGroup entity = new DataDictionaryGroup();
		entity.setGroupName(dto.getGroupName());
		if (dto.getGroupCode() != null) {
			entity.setGroupCode(dto.getGroupCode());
		}
		entity.setTreeNo(categoryId);
		entity.setGroupType(dto.getGroupType());
		dataDictionaryGroupDAO.save(entity);
		dto.setGroupNo(entity.getGroupNo());
	}

	/**
	 * 删除字典分组.
	 * 
	 * @param no 分组编号
	 */
	@Transactional
	public void removeDataDictionaryGroup(Long no) {
		dataDictionaryGroupDAO.delete(dataDictionaryGroupDAO.findById(no));
	}

	/**
	 * 删除数据字典分组.
	 * 
	 * @param nos 字典分组编号.
	 */
	@Transactional
	public void removeDataDictionaryGroups(Long[] nos) {
		dataDictionaryGroupDAO.deleteByIds(nos);
	}

	/**
	 * 修改字典分组.
	 * 
	 * @param dto DTO
	 * @return DataDictionaryGroupDTO DTO
	 */
	@Transactional
	public DataDictionaryGroupDTO mergeDataDictionaryGroup(
			DataDictionaryGroupDTO dto) {
		//dto2entity(dto, entity);
		DataDictionaryGroup d= dataDictionaryGroupDAO.findById(dto.getGroupNo());
		d.setGroupName(dto.getGroupName());
		if("tree".equals(d.getGroupType())){//添加树节构
			EventCategory eventCategory = eventCategoryDAO.findById(d.getTreeNo());
			//分类名称
			eventCategory.setEventName(d.getGroupName());
			//eventCategory.setCategoryRoot(dto.getGroupCode());
			eventCategoryDAO.merge(eventCategory);
		}
		d = dataDictionaryGroupDAO.merge(d);
		entity2dto(d, dto);

		return dto;
	}

	/**
	 * 修改字典分组.
	 * 
	 * @param dto DTO
	 */
	@Transactional
	public void updateDataDictionaryGroup(DataDictionaryGroupDTO dto) {
		if ((dto.getGroupNo() != null) && (dto.getGroupName() != null)) {
			DataDictionaryGroup entity = dataDictionaryGroupDAO.findById(dto
					.getGroupNo());

			dto2entity(dto, entity);
			dataDictionaryGroupDAO.update(entity);
		}
	}

	/**
	 * 批量修改.
	 * 
	 * @param dtos 字典分组DTO集合
	 */
	@Transactional
	public void mergeAllDataDictionaryGroup(List<DataDictionaryGroupDTO> dtos) {
		List<DataDictionaryGroup> entities = new ArrayList<DataDictionaryGroup>();
		for (DataDictionaryGroupDTO dto : dtos) {
			DataDictionaryGroup entity = new DataDictionaryGroup();
			dto2entity(dto, entity);
			entities.add(entity);
		}
		dataDictionaryGroupDAO.mergeAll(entities);
	}

	/**
	 * 根据ID查找数据字典分组.
	 * 
	 * @param no 字典分组编号
	 */
	public DataDictionaryGroupDTO findDataDictionaryGroupById(Long no) {
		DataDictionaryGroupDTO dto = new DataDictionaryGroupDTO();
		DataDictionaryGroup entity = dataDictionaryGroupDAO.findById(no);
		if (entity != null) {
			entity2dto(entity, dto);
		}

		return dto;
	}

	/**
	 * 根据名称查找字典列表.
	 * 
	 * @return List<DataDictionaryGroupDTO> 字典分组集合
	 */
	public List<DataDictionaryGroupDTO> findDataDictionaryGroupByName(
			String name) {

		List<DataDictionaryGroup> entities = dataDictionaryGroupDAO.findBy(
				"groupName", name);
		List<DataDictionaryGroupDTO> dtos = new ArrayList<DataDictionaryGroupDTO>(
				entities.size());
		for (DataDictionaryGroup entity : entities) {
			DataDictionaryGroupDTO dto = new DataDictionaryGroupDTO();
			entity2dto(entity, dto);
			dtos.add(dto);
		}

		return dtos;
	}

	/**
	 * 查找数据字典分组.
	 * 
	 * @return List<DataDictionaryGroupDTO> 字典分组集合
	 */
	public List<DataDictionaryGroupDTO> findAllDataDictionaryGroup() {
		List<DataDictionaryGroup> entities = dataDictionaryGroupDAO
				.findDataDictionaryGroups();
		List<DataDictionaryGroupDTO> dtos = new ArrayList<DataDictionaryGroupDTO>();
		for (DataDictionaryGroup entity : entities) {
			DataDictionaryGroupDTO dto = new DataDictionaryGroupDTO();
			entity2dto(entity, dto);
			dtos.add(dto);
		}
		return dtos;
	}
	public List<DataDictionaryGroupDTO> findAllDataDictionaryGroupByType(String groupType) {
		List<DataDictionaryGroup> entities = dataDictionaryGroupDAO.findBy("groupType", groupType);
		List<DataDictionaryGroupDTO> dtos = new ArrayList<DataDictionaryGroupDTO>();
		for (DataDictionaryGroup entity : entities) {
			DataDictionaryGroupDTO dto = new DataDictionaryGroupDTO();
			entity2dto(entity, dto);
			dtos.add(dto);
		}
		return dtos;
	}
	/**
	 * dto2entity
	 * @param dto
	 * @param entity
	 */
	private void dto2entity(DataDictionaryGroupDTO dto,
			DataDictionaryGroup entity) {

		try {
			BeanUtils.copyProperties(entity, dto);
		} catch (Exception ex) {
			throw new ApplicationException(ex);
		}
	}

	/**
	 *  entity2dto
	 * @param entity
	 * @param dto
	 */
	private void entity2dto(DataDictionaryGroup entity,
			DataDictionaryGroupDTO dto) {
		try {
			BeanUtils.copyProperties(dto, entity);
		} catch (Exception ex) {
			throw new ApplicationException(ex);
		}
	}

	/**
	 * 导入数据方法.
	 * 
	 * @param importFile
	 * @return String
	 */
	@Transactional
	public String importDataDictionaryGroup(File importFile) {
		String result = "";
		int insert = 0;
		int update = 0;
		int total = 0;
		int failure = 0;
		Reader rd = null;
		CSVReader reader = null;
		try {
			String fileEncode = FileEncodeUtils.getFileEncode(importFile);
			rd = new InputStreamReader(new FileInputStream(importFile),fileEncode);
			reader = new CSVReader(rd);
			String[] line = null;
			try {
				Byte dataFlag=1;
				while ((line = reader.readNext()) != null) {
					if (StringUtils.hasText(line[0].toString())
							&& StringUtils.hasText(line[1].toString())) {
						DataDictionaryGroup dataDictionayGroup = new DataDictionaryGroup();
						dataDictionayGroup.setGroupName(line[0].toString());
						dataDictionayGroup.setGroupCode(line[1].toString());
						dataDictionayGroup.setDataFlag(dataFlag);
						dataDictionayGroup.setGroupType(line[2].toString());
						dataDictionaryGroupDAO.merge(dataDictionayGroup);
						insert++;
						total++;
					} else {
						failure++;
					}
				}

				result = "Total:" + total + ",&nbsp;Insert:" + insert
						+ ",&nbsp;Update:" + update + ",&nbsp;Failure:"
						+ failure;
			} catch (Exception e) {
				LOGGER.error("import DataDictionary Group",e);
				result = "IOError";
			}
		} catch (Exception e1) {
			LOGGER.error("import DataDictionary Group",e1);
			result = "FileNotFound";
		}finally {
			try {
				if(rd!=null){
					rd.close();
				}
				if(reader!=null){
					reader.close();
				}
			} catch (IOException e) {
				LOGGER.error(e);
			}
		}
		return result;
	}

	/**
	 * 导出数据
	 * @param redto
	 * @return InputStream
	 */
	@SuppressWarnings({ "static-access", "unchecked" })
	@Transactional
	public InputStream exportDataDictionaryGroup(
			DataDictionaryGroupQueryDTO redto) {
		StringWriter sw = new StringWriter();
		CSVWriter csvw = new CSVWriter(sw);
		List<String[]> data = new ArrayList<String[]>();
		LanguageContent lc = LanguageContent.getInstance();
		data.add(new String[] { lc.getContent("common.id"),
				lc.getContent("label.role.roleName"),
				lc.getContent("common.code") ,lc.getContent("label.type")});
		redto.setLimit(csvw.EXPORT_SIZE);
		PageDTO p = dataDictionaryGroupDAO.findpager(redto);
		if (p != null && p.getData() != null && p.getData().size() > 0) {
			List<DataDictionaryGroup> entities = p.getData();
			for (DataDictionaryGroup entity : entities) {
				data.add(new String[] { entity.getGroupNo().toString(),
						entity.getGroupName(), entity.getGroupCode(), entity.getGroupType() });
			}
		}
		csvw.writeAll(data);
		byte[] bs = null;
		try {
			bs = sw.getBuffer().toString().getBytes("GBK");
		} catch (UnsupportedEncodingException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		ByteArrayInputStream stream = null;
		if(bs!=null){
			stream = new ByteArrayInputStream(bs);
		}
		try {
        	if(csvw!=null){
        		csvw.flush();
    			csvw.close();
        	}
			if(sw!=null){
				sw.flush();
				sw.close();
			}
		} catch (IOException e) {
			LOGGER.error(e);
		}
		return stream;
	}
}
